#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(200, 100, 1440, 860);
    this->setWindowTitle("Digital Image Process Programming Platform");
    this->setWindowIcon(QIcon("../../appicon.svg"));

    /*******************************************************/
    // 菜单栏
    /*******************************************************/
    
    menuBar = new QMenuBar(this);
    menuBar->setGeometry(0, 0, 1440, 30);
    
    /*******************************************************/
    // 用来承载图片或文字的组件
    /*******************************************************/
    labelSrc = new QLabel(this);
    labelDst = new QLabel(this);
    labelExt = new QLabel(this);
    labelSrc->move(40, 20);
    labelDst->move(40, 20);
    labelExt->move(40, 20);
    
    
    /*******************************************************/
    // 文件菜单
    /*******************************************************/
    menuFile = new QMenu("文件", this);
    actOpen = new QAction("打开", this);
    actOpenDir = new QAction("打开目录", this);
    actClose = new QAction("关闭", this);
    actQuit = new QAction("退出", this);
    actNext = new QAction("下一张", this);
    actPrev = new QAction("上一张", this);
    menuFile->addAction(actOpen);
    menuFile->addAction(actOpenDir);
    menuFile->addAction(actClose);
    menuFile->addAction(actQuit);
    menuFile->addAction(actNext);
    menuFile->addAction(actPrev);
    /*******************************************************/
    //
    /*******************************************************/
    actPlotHist = new QAction("绘制直方图", this);

    /*******************************************************/
    // 灰度变换
    /*******************************************************/
    menuGray = new QMenu("灰度变换", this);
    actHistEql = new QAction("直方图均衡", this);
    actExpon = new QAction("幂次变换", this);
    menuGray->addAction(actHistEql);
    menuGray->addAction(actExpon);
    /***************************************/
    
    menuBar->addMenu(menuFile);
    menuBar->addAction(actPlotHist);
    menuBar->addMenu(menuGray);
    
    /***************************************/



    connect(actOpen, &QAction::triggered, this, &MainWindow::slotOpen);
    connect(actClose, &QAction::triggered, this, &MainWindow::slotClose);
    connect(actQuit, &QAction::triggered, this, &MainWindow::close);
    connect(actPlotHist, &QAction::triggered, this, &MainWindow::slotPlotHist);
    connect(actHistEql, &QAction::triggered, this, &MainWindow::slotHistEql);
}


/******************************************/
// 槽函数 //

// 打开图片
void MainWindow::slotOpen(){
    QFileDialog dialog(this);
    QSettings setting("./setting.ini", QSettings::IniFormat);  //QSettings能记录一些程序中的信息，下次再打开时可以读取出来
    QString lastPath = setting.value("LastFilePath").toString();  //获取上次的打开路径
    QString fileName = dialog.getOpenFileName(this, "打开文件", lastPath,"*.raw *.bmp");
    if (fileName.isEmpty()){
        return;
    }
    else {
        setting.setValue("LastFilePath",fileName);  //记录路径到QSetting中保存
        MainWindow::readRaw(&fileName);
    }
    if (!image){
        return;
    }
    clearFig();
    MainWindow::showImage(image, 20, 40, width, height, labelSrc);
    flagSrc = 1;
}


// 关闭图片
void MainWindow::slotClose(){
    clearFig();
}


// 绘制直方图
void MainWindow::slotPlotHist(){
    if (!flagSrc)
        return;
    calHist(image, width, height);
    int maxVal = 1;
    for (int i = 0; i < 256; i++){
        int lev = hist[i];
        if (maxVal < lev){
            maxVal = lev;
        }
    }
    float k = 390.0 / maxVal;
    for (int i = 0; i < 256; i++){
        int lev = hist[i];
        hist[i] = lev * k;
    }
    for (int i = 399; i >= 0; i--){
        for (int j = 1279; j >= 0; j--){
            if (j%5 == 0){
                int h = hist[j/5];
                if (h - i > 0){
                    figHist[(399-i)*1280+j] = 0;
                }
                else{
                    figHist[(399-i)*1280+j] = 240;
                }
            }
            else{
                figHist[(399-i)*1280+j] = 240;
            }
        }
    }
    MainWindow::showImage(figHist, 20, 40+height, 1280, 400, labelDst);
    flagDst = 1;
    return;

}


void MainWindow::slotHistEql(){
    if (!flagSrc)
        return;
    uint8_t outImg[width*height];
    histEql(image, width, height, outImg);
    MainWindow::showImage(outImg, 40+width, 40, width, height, labelDst);
    flagDst = 1;
    return;
}


void MainWindow::slotExpon(){
    if (!flagSrc)
        return;
    uint8_t outImg[width*height];
    exponTrans(image, width, height, outImg);
    showImage(outImg, 40+width, 40, width, height, labelDst);
    flagDst = 1;
    return;
}

/******************************************/
// 功能函数

//
void MainWindow::readRaw(QString * fileName){
    QByteArray ba = fileName->toLocal8Bit();
    const char *filename=ba.data();  // QString类型转换为const char
    FILE* fpImg;
    fpImg = fopen(filename, "rb");  // 读文件
    fread(&width, sizeof(int), 1, fpImg);
    fread(&height, sizeof(int), 1, fpImg);
    image = new uint8_t[width * height];
    fread(image, sizeof(uint8_t), width * height, fpImg);
    fclose(fpImg);
}


// 图像显示
void MainWindow::showImage(uint8_t * src, int x, int y, int w, int h, QLabel * label){
    QImage Img(w, h, QImage::Format_RGB32);
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            int gray;
            QRgb value;
            gray = src[i*w+j];
            value = qRgb(gray, gray, gray);
            Img.setPixel(j, i, value);
        }
    }
    QPixmap pixmap;
    pixmap = QPixmap::fromImage(Img);
    label->setPixmap(pixmap);
    label->setGeometry(x, y, w, h);
    label->show();
    label->raise();
}

// 计算直方图
void MainWindow::calHist(uint8_t * src, int w, int h){
    if (!flagSrc)
        return;
    for (int i = 0; i < 256; i++)
        hist[i] = 0;
    int size = w * h;
    for (int i = 0; i < size; i++){
        uint8_t gray = src[i];
        hist[gray]++;
    }
    flagHist = 1;
}

// 直方图均衡
void MainWindow::histEql(uint8_t * src, int w, int h, uint8_t * dst){
    calHist(src, w, h);
    float histCDF[256];
    int histMap[256];
    for (int i = 0; i < 256; i++){
        if (i == 0){
            histCDF[i] = hist[i];
        }
        else{
            histCDF[i] = hist[i] + histCDF[i-1];
        }
        histMap[i] = i;
    }
    float k = 255.0 / (w * h);
    for (int i = 0; i < 256; i++){
        histMap[i] = k * histCDF[i];
    }
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            dst[i*w+j] = histMap[src[i*w+j]];
        }
    }
    return;

}

// 幂次变换
void MainWindow::exponTrans(uint8_t * src, int w, int h, uint8_t * dst, float gamma){
    
    
}


// 清空图片显示
void MainWindow::clearFig(){
    if (flagSrc) {
        labelSrc->clear();
        flagSrc = 0;
    }
    if (flagDst) {
        labelDst->clear();
        flagDst = 0;
    }
    if (flagExt) {
        labelExt->clear();
        flagExt = 0;
    }
    if (flagHist) {
        flagHist = 0;
    }
}

MainWindow::~MainWindow()
{
}

